// @author: caoshi
// @date: 2021-05-03 20:38
// 缓冲通道
/**
非缓冲通道: make(chan T)
	一次发送, 一次接收, 都是阻塞的
	默认容量是0
缓冲通道: make(chan T, capacity)
	发送: 缓冲区的数据满了, 才会阻塞
	接收: 缓冲区的数据空了, 才会阻塞
*/
package main

import (
	"fmt"
	"strconv"
)

func main() {
	// 非缓冲通道
	ch1 := make(chan int)
	fmt.Println(len(ch1), cap(ch1)) // 0 0

	// 缓冲通道, 缓冲区的大小是5
	ch2 := make(chan int, 5)
	fmt.Println(len(ch2), cap(ch2)) // 0 5

	ch2 <- 100
	fmt.Println(len(ch2), cap(ch2)) // 1 5
	ch2 <- 200
	ch2 <- 300
	ch2 <- 400
	ch2 <- 500
	fmt.Println(len(ch2), cap(ch2))
	// ch2 <- 600		// 进入阻塞, 需要进行读操作来解除缓冲

	fmt.Println("---------------------------")
	ch3 := make(chan string, 4)

	go sendDataBuf(ch3)
	for {
		v, ok := <-ch3
		if !ok {
			fmt.Println("读取完毕!")
			break
		}
		fmt.Println("\t主groutine读到的数据是: ", v)
	}

	fmt.Println("main over")

}

func sendDataBuf(ch chan string) {
	for i := 0; i < 10; i++ {
		ch <- "数据" + strconv.Itoa(i)
		fmt.Printf("子groutine中写入第 %d 个数据\n", i)
	}
	close(ch)
}
